package org.bootstrap.annotation.impl;


import cn.hutool.core.lang.Console;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HtmlUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.bootstrap.annotation.TokenValidate;
import org.bootstrap.entity.UserInfo;
import org.bootstrap.service.Impl.UserServiceImpl;
import org.bootstrap.tool.BooleanOptional;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Objects;

@Aspect
@Component
@SuppressWarnings("unused")
public class TokenValidateImpl {

    @Resource
    private UserServiceImpl userService;


    private static JSONObject jsonResult = null;

    /**
     * @param token  令牌
     * @param db     是否连接数据库核对
     * @param hidden 隐藏返回隐私信息
     * @return json
     */
    private JSONObject run(String token, boolean db, boolean hidden) {
        JSONObject res = JSONUtil.createObj();
        BooleanOptional.of(StrUtil.isNotEmpty(token)).isTrue(y -> {
            JSONObject _info = userService.verity_token_width_db(token, db);
            String user_id = _info.getStr("user_id");
            BooleanOptional.of(StrUtil.isNotEmpty(user_id)).isTrue(t -> {
                UserInfo userInfo = userService.get_user_info(user_id);
                BooleanOptional.of(ObjectUtil.isNotNull(userInfo)).isTrue(h -> {
                    BooleanOptional.of(hidden).isFalse(q -> res.putOpt("user_info", userInfo)).isTrue(w -> {
                        res.putOpt("success", true);// 直接返回用户信息
                    });
                });
            });
        });
        return res;
    }


    @Around(value = "@annotation(org.bootstrap.annotation.TokenValidate)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        Hashtable<String, Object> params = new Hashtable<>(); // 参数映射
        jsonResult = JSONUtil.createObj();
        if (!jsonResult.isEmpty()) {
            jsonResult.clear();// 清空数据
        }
        Object[] args = joinPoint.getArgs();// 获取方法参数
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        TokenValidate tokenValidate = methodSignature.getMethod().getAnnotation(TokenValidate.class);
        Method method = methodSignature.getMethod();
        String[] values = tokenValidate.value(); // 验证的字段值
        boolean hidden_info = tokenValidate.hidden_info(); // 验证的字段值
        String[] parameterNames = methodSignature.getParameterNames();
        for (int i = 0; i < parameterNames.length; i++) {
            Object arg = args[i];
            if (Objects.nonNull(arg)) {
                params.put(parameterNames[i], args[i]);
            }
        }
        boolean need_check = tokenValidate.auth_check(); // 是否要和数据库对比
        for (String key : values) {
            if (params.containsKey(key)) {
                Object data = params.getOrDefault(key, null);
                if (Objects.nonNull(data)) {
                    try {
                        String _token = "";
                        if (data instanceof HashMap) {
                            HashMap<String, String> map = (HashMap<String, String>) data;
                            String[] props = tokenValidate.fileds();
                            for (String prop : props) {
                                Object val = map.getOrDefault(prop, null);
                                if (ObjectUtil.isNotNull(val)) {
                                    _token = val.toString();
                                }
                            }
                        } else {
                            _token = HtmlUtil.filter(StrUtil.toString(data));// 转为字符串
                        }
                        jsonResult = run(_token, need_check, hidden_info);

                    } catch (Exception e) {
                        Console.error(e.getMessage());
                    }
                }
            }
        }
        Object os = joinPoint.proceed();
        if (jsonResult.isEmpty()) {
            jsonResult.putOpt("code", 400)
                    .putOpt("message", "当前无权限访问")
                    .putOpt("login", false);
        }
        os = jsonResult;
        return os;
    }

    @Pointcut("@annotation(org.bootstrap.annotation.TokenValidate)")
    public void pointcut() {

    }

}
